package com.saic.data.util;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.output.ThresholdingOutputStream;
import org.apache.hadoop.fs.ftp.FTPException;

import it.sauronsoftware.ftp4j.FTPAbortedException;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferException;
import it.sauronsoftware.ftp4j.FTPFile;
import it.sauronsoftware.ftp4j.FTPIllegalReplyException;
import it.sauronsoftware.ftp4j.FTPListParseException;

public class FTPUtil {

	private FTPClient client = null;
	private String remoteDir = "/";
	private String host;
	private String user;
	private String pwd;

	/**
	 * @登陆FTP服务器
	 * @param host
	 * @param user
	 * @param pwd
	 * @return
	 * @throws SocketException
	 * @throws IOException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public boolean login(String host, String user, String pwd)
			throws SocketException, IOException, IllegalStateException,
			FTPIllegalReplyException, FTPException,
			it.sauronsoftware.ftp4j.FTPException {
		this.host = host;
		this.user = user;
		this.pwd = pwd;
		return login(host, user, pwd, "");
	}

	/**
	 * @登陆
	 * @param host
	 * @param user
	 * @param pwd
	 * @return
	 * @throws IOException
	 * @throws SocketException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public boolean login(String host, String user, String pwd, String remoteDir)
			throws SocketException, IOException, IllegalStateException,
			FTPIllegalReplyException, FTPException,
			it.sauronsoftware.ftp4j.FTPException {

		this.host = host;
		this.user = user;
		this.pwd = pwd;

		client = new FTPClient();
		client.connect(host);
		client.login(user, pwd);
		client.setPassive(true);
		client.setAutoNoopTimeout(30000);
		this.remoteDir = remoteDir;
        
		return true;
	}

	/***
	 * @得到文件名
	 * @return
	 * @throws IOException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws FTPListParseException
	 * @throws FTPAbortedException
	 * @throws FTPDataTransferException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public List<FTPFile> getNames(boolean deep, String dir) throws IOException,
			IllegalStateException, FTPIllegalReplyException, FTPException,
			FTPDataTransferException, FTPAbortedException,
			FTPListParseException, it.sauronsoftware.ftp4j.FTPException {
		
		pm(this.getClass(),"check /"+dir);
		client.changeDirectory(dir);
		List<FTPFile> names = new ArrayList<FTPFile>();
		if (null != client) {
			pm(this.getClass(),"list files");
			names = checkDirectory(names, client, deep);
		}
		client.changeDirectoryUp();
		return names;
	}

	/**
	 * @DESC:复制文件
	 * @param fileName
	 * @param out
	 * @return
	 * @throws IOException
	 * @throws FTPAbortedException
	 * @throws FTPDataTransferException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public boolean copyFile(String path, OutputStream out) throws IOException,
			IllegalStateException, FTPIllegalReplyException, FTPException,
			FTPDataTransferException, FTPAbortedException,
			it.sauronsoftware.ftp4j.FTPException {
		pm(this.getClass(),"download from"+client.currentDirectory());
		path = client.currentDirectory() + "/" + path;
		client.download(path, out, 0, null);
		return true;
	}

	/**
	 * @DESC:从FTP上删除文件
	 * @param f
	 * @return
	 * @throws IOException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public boolean delete(FTPFile f) throws IOException, IllegalStateException,
			FTPIllegalReplyException, FTPException,
			it.sauronsoftware.ftp4j.FTPException {
		client.deleteFile(client.currentDirectory() + "/" + f.getName());
		return true;
	}

	public void download(String src, String localFolderPath, String ftpDir)
			throws Exception {
		File localFolder = new File(localFolderPath);
		if (localFolder.isFile()) { 
            throw new Exception("所要的下载保存的地方是一个文件，无法保存！"); 
		} else { 
            if (!localFolder.exists()) localFolder.mkdirs(); 
		}
		client.download(client.currentDirectory() + "/" + ftpDir + "/" + src, new File(localFolder+"/"+src));

	}
    
	
	
	
	/**
	 * @列出文件
	 * @param client
	 * @param deep
	 * @return
	 * @throws IOException
	 * @throws FTPListParseException
	 * @throws FTPAbortedException
	 * @throws FTPDataTransferException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public List<FTPFile> getNames(FTPClient client, boolean deep)
			throws IOException, IllegalStateException,
			FTPIllegalReplyException, FTPException, FTPDataTransferException,
			FTPAbortedException, FTPListParseException,
			it.sauronsoftware.ftp4j.FTPException {
		List<FTPFile> names = new ArrayList<FTPFile>();
		if (null != client) {
			names = checkDirectory(names, client, deep);
		}
		return names;
	}

	/**
	 * @获取文件名称
	 * @return
	 * @throws IOException
	 * @throws FTPListParseException
	 * @throws FTPAbortedException
	 * @throws FTPDataTransferException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public List<FTPFile> getFTPFiles() throws IOException,
			IllegalStateException, FTPIllegalReplyException, FTPException,
			FTPDataTransferException, FTPAbortedException,
			FTPListParseException, it.sauronsoftware.ftp4j.FTPException {

		List<FTPFile> list = new ArrayList<FTPFile>();
		if (client != null) {
			FTPFile[] files;
			files = client.list(this.remoteDir);
			for (int i = 0; i < files.length; i++) {
				FTPFile file = files[i];
				String name = file.getName();
				if (name.equals(".") || name.equals(".."))
					continue;
				else if (file.getType() == FTPFile.TYPE_FILE)
					list.add(file);
			}
		}
		return list;
	}

	/**
	 * @DESC:重新登陆FTP服务器
	 * @throws IOException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public void relogin() throws IOException, IllegalStateException,
			FTPIllegalReplyException, FTPException,
			it.sauronsoftware.ftp4j.FTPException {
		pm(this.getClass(),"Relogin FTP");
		client.logout();
		login(host, user, pwd);
	}

	/**
	 * @检查文件夹
	 * @param names
	 * @param client
	 * @param deep
	 * @return
	 * @throws FTPListParseException
	 * @throws FTPAbortedException
	 * @throws FTPDataTransferException
	 * @throws FTPException
	 * @throws FTPIllegalReplyException
	 * @throws IllegalStateException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 * @throws IOException
	 */
	public  List<FTPFile> checkDirectory(List<FTPFile> names,
			FTPClient client, boolean deep) throws IllegalStateException,
			FTPIllegalReplyException, FTPException, FTPDataTransferException,
			FTPAbortedException, FTPListParseException,
			it.sauronsoftware.ftp4j.FTPException, IOException {
        
        pm(this.getClass(),"currentDirectory: "+client.currentDirectory());
       	FTPFile[] files = client.list(client.currentDirectory());
		for (int i = 0; i < files.length; i++) {
			FTPFile file = files[i];
			String name = file.getName();
			if (name.equals(".") || name.equals(".."))
				continue;
			if (deep && file.getType() == FTPFile.TYPE_DIRECTORY) {
				client.changeDirectory(client.currentDirectory() + "/" + name);
				names = checkDirectory(names, client, deep);
				client.changeDirectoryUp();
			} else if (file.getType() == FTPFile.TYPE_FILE) {
				names.add(file);
			}
		}
		return names;
	}

	/**
	 * @DESC:logout
	 * @throws IllegalStateException
	 * @throws IOException
	 * @throws FTPIllegalReplyException
	 * @throws FTPException
	 * @throws it.sauronsoftware.ftp4j.FTPException
	 */
	public void logout() throws IllegalStateException, IOException,
			FTPIllegalReplyException, FTPException,
			it.sauronsoftware.ftp4j.FTPException {
		if (null != client) {
			client.disconnect(true);
		}
	}

	public  String getRemoteDir() {
		return remoteDir;
	}
    
	public  void reconnect() throws IllegalStateException, IOException, FTPIllegalReplyException, it.sauronsoftware.ftp4j.FTPException {
		client.disconnect(false);
		client.connect(host);
		client.login(user, pwd);
		client.setPassive(true);
	}
	
	private void pm(Class<?> cls, String msg) {
		pm(cls.getName(), msg);
	}

	private void pm(String cls, String msg) {
		String data = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
		System.out.println("["+data+"] Print by " + cls + "-->" + msg);
	}
}
